package com.kdg.base;

import java.util.HashSet;
import java.util.Set;

/**
 * String的深入理解
 * Created by kong on 2018/6/12.
 */
public class StringDeep {
    public static void main(String[] args) throws InterruptedException {
        String a = "chenssy";
        String b = "chenssy";
        String c = new String("chenssy");
        String d = "chen" + "ssy";
        String e = "chen";
        String f = "ssy";
        String g = e + f;
        System.out.println(a == b);  //true
        System.out.println(a == c);  //false
        System.out.println(d == a);  //true   一个字符串由多个字符串常量连接而成时，它自己肯定也是字符串常量
        System.out.println(a == g);  //false  //JVM对String e="chen"对象放在常量池中是在编译时做的，而String g=e+f是在运行时刻才能知道的。new对象也是在运行时才做的。
        System.out.println(a == g.intern());  //true
        System.out.println(a.intern() == b.intern());  //true

        //编译期优化
        String str = "a1";
        String str1 = "a" + 1;
        System.out.println(str == str1);  //true  在程序编译期，JVM将常量字符串的 “+” 连接优化为连接优化后的值，即在编译期字符串常量的值就定下来了

        //编译期无法确定
        String str3 = "ab2";
        String str4 = "ab";
        String str5 = str4 + 2;
        System.out.println(str3 == str5);  //false  由于“+”的连接中有字符串引用的存在，而引用的值在程序编译期无法确定，所以只有在运行时动态分配并将连接后的新地址赋给s2

        //有关final
        String str32 = "ab2";
        final String str42 = "ab";
        String str52 = str42 + 2;
        System.out.println(str32 == str52);  //true
        //总结来说就是：字面量"+"拼接是在编译期间进行的，拼接后的字符串存放在字符串池中；而字符串引用的"+"拼接运算实在运行时进行的，新创建的字符串存放在堆中(引用的拼接要排除final关键字的修饰)，因为final修饰的变量它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。

    }
}
